#include <iostream>
#include <thread>

using namespace std;

/* void do_something(int i, string const &s){ */

/*     for(int j = 0; j < i; ++j) */
/*     { */
/*         cout << s << endl; */
/*     } */

/*     return; */
/* } */

/* void test1(){ */
/*     //even the parameter pass by reference */
/*     //by system also will copy parameter into new child thread */
/*     //if the buffer of string is very long */
/*     //main thread might be exit before child thread complete copy of the string */
/*     //so main thread join/detach is needed */
/*     thread t(do_something, 3, "hello"); */

/*     t.join(); */
/*     return; */
/* } */

void update(int & i){
    i++;

    return;
}

void oops(int i){
    //thread object template is
    //template<class Function, class ... Args>
    //explicit thread(Function &&f, Args &&... args);
    //is move construct
    //need a explain

    //thread t(update, i);//error
    thread t(update, ref(i));

    cout << "i = " << i << endl;

    t.join();

    cout << "i = " << i << endl;

    return;
}

//pass parameter
//pass member function
/* class X */
/* { */
/* public: */
/*     void do_lengthy_work(){ */
/*         cout << "do lengthy do_lengthy_work" << endl; */
/*     } */

/*     void do_lengthy_work(int i){ */
/*         cout << "do work i = " << i << endl; */
/*     } */
/* }; */

/* void test2(){ */
/*     X my_x; */

/*     thread t1(&X::do_lengthy_work, &my_x); */

/*     int i = 1; */
/*     thread t2(&X::do_lengthy_work, &my_x, i); */

/*     t1.detach(); */
/*     t2.join(); */

/*     return; */
/* } */

//use move construct to create thread
/* void process_big_object(std::unique_ptr<big_object>); */
/* std::unique_ptr<big_object> p(new big_object); */
/* p->prepare_data(42); */
/* std::thread t(process_big_object,std::move(p)); */


int main()
{
    /* test1(); */
    /* int i = 1; */
    /* oops(i); */
    /* test2(); */

    return 0;
}

